package chan.project.template;

import chan.project.config.CosClientConfig;
import chan.project.manager.CosManager;
import chan.project.model.dto.file.UploadPictureResult;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.RandomUtil;
import com.qcloud.cos.model.PutObjectResult;
import com.qcloud.cos.model.ciModel.persistence.ImageInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.File;
import java.io.IOException;
import java.util.Date;

@Slf4j
@Component
public abstract class PictureUploadTemplate {

    @Resource
    private CosManager cosManager;

    @Resource
    private CosClientConfig cosClientConfig;

    /**
     * 上传图片并校验
     * @param inputSource 文件
     * @param uploadPathPreFix 文件存储前缀
     * @return
     */
    public UploadPictureResult uploadPicture(Object inputSource, String uploadPathPreFix){
        validFile(inputSource);
        //图片存储的名称是时间戳+uuid+文件后缀
        String uuid = RandomUtil.randomString(16);
        String originalFilename = getOriginalFilename(inputSource);
        String uploadFileName = String.format("%s_%s.%s", DateUtil.formatDate(new Date()), uuid, FileUtil.getSuffix(originalFilename));
        //文件路径是文件传输的前缀/文件名称
        String filePath = String.format("/%s/%s", uploadPathPreFix, uploadFileName);
        File file = null;
        try {
            //创建临时文件
            file = File.createTempFile(filePath,null);
            //保存临时文件
            saveFile(inputSource,file);
            //上传文件
            PutObjectResult putObjectResult = cosManager.putPictureObject(filePath, file);
            ImageInfo imageInfo = putObjectResult.getCiUploadResult().getOriginalInfo().getImageInfo();
            //封装返回结果
            return packagingResult(imageInfo, originalFilename, file, filePath);
        } catch (IOException e) {
            log.error("上传失败");
            throw new RuntimeException(e);
        } finally {
            deleteFile(file);
        }
    }

    public abstract void validFile(Object inputSource);

    public abstract String getOriginalFilename(Object inputSource);

    public abstract void saveFile(Object inputSource, File file) throws IOException;

    /**
     * 封装返回结果
     * @param imageInfo
     * @param originalFilename
     * @param file
     * @param filePath
     * @return 返回封装结果
     */
    public UploadPictureResult packagingResult(ImageInfo imageInfo,String originalFilename,File file,String filePath){
        UploadPictureResult uploadPictureResult = new UploadPictureResult();
        int picWidth = imageInfo.getWidth();
        int picHeight = imageInfo.getHeight();
        double picScale = NumberUtil.round(picWidth * 1.0 / picHeight,2).doubleValue();
        uploadPictureResult.setPicName(FileUtil.mainName(originalFilename));
        uploadPictureResult.setPicSize(FileUtil.size(file));
        uploadPictureResult.setPicWidth(picWidth);
        uploadPictureResult.setPicHeight(picHeight);
        uploadPictureResult.setPicScale(picScale);
        uploadPictureResult.setPicFormat(imageInfo.getFormat());
        uploadPictureResult.setUrl(cosClientConfig.getHost() + "/" + filePath);
        return uploadPictureResult;
    }

    /**
     * 删除临时文件
     * @param file
     */
    public void deleteFile(File file){
        if(file == null){
            return;
        }
        boolean delete = file.delete();
        if(!delete){
            log.error("删除失败,请及时删除文件{}防止内存溢出",file.getAbsoluteFile());
        }
    }
}
